home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / dnsconf / origin.c < prev    next >
C/C++ Source or Header  |  1996-06-30  |  5KB  |  247 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5. #include "dnsconf.h"
  6. #include "internal.h"
  7.  
  8. /*
  9.     fgets with support for continuation line
  10. */
  11. static char *record_fgets(
  12.     char *buf,
  13.     int size,
  14.     FILE *fin)
  15. {
  16.     char *ret = NULL;
  17.     bool cont = false;
  18.     while (fgets(buf,size,fin)!=NULL){
  19.         if (ret == NULL) ret = buf;
  20.         char *ptp = strchr (buf,';');
  21.         if (ptp != NULL) *ptp = '\0';
  22.         char *ptc = strchr (buf,'(');
  23.         char *pte = strchr (buf,')');
  24.         if (ptc != NULL){
  25.             // Openning parenthese 
  26.             *ptc = ' ';
  27.             cont = true;
  28.         }else if (pte != NULL){
  29.             // Closing parenthese 
  30.             *pte = ' ';
  31.             cont = false;
  32.         }
  33.         if (!cont) break;
  34.         int len = strlen(buf);
  35.         buf += len;
  36.         size -= len;
  37.     }
  38.     return ret;
  39. }
  40.  
  41.  
  42. PUBLIC ORIGIN::ORIGIN (const char *_origin)
  43. {
  44.     origin.setfrom (_origin);
  45. }
  46.  
  47. PUBLIC void ORIGIN::print(bool save_ori, TBFILE &tbf) const
  48. {
  49.     // We don't put $ORIGIN at the beginning of the file
  50.     // because it is implied
  51.     if (save_ori) fprintf (tbf.cur,"$ORIGIN %s\n",origin.get());
  52.     tbrec.save(tbf);
  53. }
  54.  
  55. PUBLIC void ORIGIN::edit()
  56. {
  57. }
  58.  
  59. /*
  60.     Locate all IP number in use in that area (sub origin) of a domain.
  61.     Return the number added to adrs
  62. */
  63. PUBLIC int ORIGIN::getalladr(IP_ADDRS &adrs)
  64. {
  65.     int ret = 0;
  66.     int n = tbrec.getnb();
  67.     for (int i=0; i<n; i++){
  68.         RECORD *rec = tbrec.getitem(i);
  69.         if (rec->is(RTYPE_A)){
  70.             RECORD_IN_A *in = (RECORD_IN_A*)rec;
  71.             adrs.add (new IP_ADDR(in->addr));
  72.             ret++;
  73.         }
  74.     }
  75.     return ret;
  76. }
  77.  
  78.  
  79. /*
  80.     Return != if any component of the ORIGIN was modified
  81. */
  82. PUBLIC int ORIGIN::was_modified()
  83. {
  84.     int ret = ARRAY_OBJ::was_modified();
  85.     if (!ret){
  86.         ret = tbrec.was_modified();
  87.     }
  88.     return ret;
  89. }
  90.  
  91.  
  92. PRIVATE int ORIGINS::parsespecial(
  93.     const char *key,
  94.     const char *pt,
  95.     TBFILE &tbf,
  96.     ORIGIN *&ori)
  97. {
  98.     int ret = 0;
  99.     pt = str_skip(pt);
  100.     char arg[200];
  101.     pt = str_copyword (arg,pt);
  102.     if (stricmp(key,"$ORIGIN")==0){
  103.         ori = new ORIGIN(arg);
  104.         add (ori);
  105.     }else if (stricmp(key,"$INCLUDE")==0){
  106.         ori->tbrec.add (new RECORD_INCLUDE(arg));
  107.         ret = tbf.fopen (arg,"r") != NULL ? 0 : -1;
  108.     }else{
  109.         ret = -1;
  110.     }
  111.     return ret;
  112. }
  113. /*
  114.     Complete the parsing of the line, pt point to the TTL maybe
  115.     Return NULL if any error or a new RECORD.
  116. */
  117. PRIVATE int ORIGINS::parseend (
  118.     char *pt,
  119.     RECORD_PARSE &p,
  120.     ORIGIN *ori)
  121. {
  122.     int ret = -1;
  123.     pt = str_skip(pt);
  124.     if (isdigit(*pt)){
  125.         p.ttl = atoi(pt);
  126.         p.nottl = false;
  127.         while (isdigit(*pt)) pt++;
  128.         pt = str_skip(pt);
  129.     }
  130.     char keyword[200];
  131.     pt = str_copyword (keyword,pt);
  132.     if (stricmp(keyword,"IN")==0){
  133.         pt = str_skip(pt);
  134.         pt = str_copyword (keyword,pt);
  135.         pt = str_skip(pt);
  136.         pt = str_copyword (p.f2,pt);
  137.         pt = str_skip(pt);
  138.         pt = str_copyword (p.f3,pt);
  139.         pt = str_skip(pt);
  140.         pt = str_copyword (p.f4,pt);
  141.         pt = str_skip(pt);
  142.         pt = str_copyword (p.f5,pt);
  143.         pt = str_skip(pt);
  144.         pt = str_copyword (p.f6,pt);
  145.         pt = str_skip(pt);
  146.         pt = str_copyword (p.f7,pt);
  147.         pt = str_skip(pt);
  148.         pt = str_copyword (p.f8,pt);
  149.         RECORD *o = NULL;
  150.         if (stricmp(keyword,"A")==0){
  151.             o = new RECORD_IN_A(p);
  152.         }else if (stricmp(keyword,"MX")==0){
  153.             o = new RECORD_IN_MX(p);
  154.         }else if (stricmp(keyword,"NS")==0){
  155.             o = new RECORD_IN_NS(p);
  156.         }else if (stricmp(keyword,"PTR")==0){
  157.             o = new RECORD_IN_PTR(p);
  158.         }else if (stricmp(keyword,"CNAME")==0){
  159.             o = new RECORD_IN_CNAME(p);
  160.         }else if (stricmp(keyword,"SOA")==0){
  161.             o = new RECORD_IN_SOA(p);
  162.         }
  163.         if (o != NULL){
  164.             ori->tbrec.add(o);
  165.             ret = 0;
  166.         }else{
  167.             ret = -1;
  168.         }
  169.     }
  170.     return ret;
  171. }
  172.  
  173.  
  174. PUBLIC ORIGIN *ORIGINS::getitem(int no) const
  175. {
  176.     return (ORIGIN*)ARRAY::getitem(no);
  177. }
  178.  
  179. /*
  180.     Read a file with a bunch of IN records and manage those.
  181. */
  182. PUBLIC int ORIGINS::read (
  183.     const char *named_dir,
  184.     const char *fname,
  185.     const char *first_origin)
  186. {
  187.     /*
  188.         Reading a record file is complicate. It may contain
  189.         several $origin statement and several $include statement.
  190.  
  191.         We maintain the records as a set of several origin related
  192.         list. In those list, we maintain special record indicating
  193.         the beginning and end of an include file scope.
  194.     */
  195.     ORIGIN *ori = new ORIGIN(first_origin);
  196.     add (ori);
  197.     int ret = -1;
  198.     TBFILE tbf(named_dir);
  199.     tbf.fopen(fname,"r");
  200.     while (tbf.cur != NULL){
  201.         char buf[10000];
  202.         ret = 0;
  203.         while (record_fgets(buf,sizeof(buf)-1,tbf.cur)!=NULL){
  204.             strip_end (buf);
  205.             RECORD_PARSE parse;
  206.             if (buf[0] > ' ' && buf[0] != ';'){
  207.                 char *pt = str_copyword (parse.f1,buf);
  208.                 if (parse.f1[0] == '$'){
  209.                     ret = parsespecial (parse.f1,pt
  210.                         ,tbf,ori);
  211.                 }else{
  212.                     ret = parseend (pt,parse,ori);
  213.                 }
  214.             }else if (buf[0] != '\0'){
  215.                 char *pt = str_skip (buf);
  216.                 if (*pt == ';'){
  217.                     ori->tbrec.add (new RECORD_COMMENT(buf));
  218.                 }else{
  219.                     ret = parseend (pt,parse,ori);
  220.                 }
  221.             }
  222.         }
  223.         tbf.fclose ();
  224.         if (tbf.cur != NULL) ori->tbrec.add (new RECORD_END_INCLUDE);
  225.     }
  226.     return ret;
  227. }
  228.  
  229. /*
  230.     Save in a file a bunch of IN records.
  231. */
  232. PUBLIC int ORIGINS::save (
  233.     const char *named_dir,
  234.     const char *fname) const
  235. {
  236.     int ret = -1;
  237.     TBFILE tbf(named_dir);
  238.     if (tbf.fopen(fname,"w") != NULL){
  239.         ret = 0;
  240.         for (int i=0; i<getnb(); i++){
  241.             getitem(i)->print (i != 0 ,tbf);
  242.         }
  243.     }
  244.     return ret;
  245. }
  246.  
  247.